﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Data.OleDb;
using System.Data.SqlClient;
using System.IO;
using System.Linq;
using System.Text;
using ICSharpCode.SharpZipLib.Zip;

namespace Sunfish.MyBook66Interface
{
    public class mb
    {
        #region 声明

        private OleDbConnection oc;
        public DataTable chapters;
        public DataTable library;
        public DataTable books;
        private string mybookDir;
        public Hashtable chapter_book_cache;

        #endregion 声明

        #region SQL

        private readonly string sqlGetBookInfo = @"select novelid,novelname,author,listurl,brief,bookimg,lb from book_novel order by displayorder asc";
        private readonly string sqlGetLibrary = @"select dm,mc,topdm from dic_noveltype order by dm asc";
        private readonly string sqlGetChapter = @"select id,title,novelid,volume from book_novelcontent order by displayorder";

        #endregion SQL

        /// <summary>
        /// 构建函数
        /// </summary>
        /// <param name="dir">mybook66 程序所在位置</param>
        public mb(string dir)
        {
            mybookDir = dir;
            oc = new OleDbConnection(
            string.Format("Provider=Microsoft.Jet.OLEDB.4.0;Data Source={0}\\pim.mdb", dir));
            oc.Open();
            this.refresh();
        }

        /// <summary>
        /// 刷新数据结构
        /// </summary>
        public void refresh()
        {
            using (OleDbDataAdapter oad = new OleDbDataAdapter(sqlGetBookInfo, oc))
            {
                books = new DataTable();
                oad.Fill(books);
            }
            using (OleDbDataAdapter oad = new OleDbDataAdapter(sqlGetLibrary, oc))
            {
                library = new DataTable();
                oad.Fill(library);
            }
            using (OleDbDataAdapter oad = new OleDbDataAdapter(sqlGetChapter, oc))
            {
                chapter_book_cache = new Hashtable();
                chapters = new DataTable();
                oad.Fill(chapters);
                foreach (DataRow item in chapters.Rows)
                {
                    chapter_book_cache.Add(item[0].ToString(), item[2].ToString());
                }
            }
        }

        /// <summary>
        /// 获取章节html流
        /// </summary>
        /// <param name="chapterID">章节id</param>
        /// <returns></returns>
        public string getChapterContent_nocache(Int64 chapterID)
        {
            using (DataView dv = new DataView(chapters, string.Format("id = \"{0}\"", chapterID.ToString()), "displayorder", DataViewRowState.CurrentRows))
            {
                string novelID = "";
                DataTable dt = dv.ToTable();
                if (dt.Rows.Count > 0)
                {
                    novelID = dt.Rows[2].ToString();
                }
                string kk = string.Format("{0}\\chm\\{1}\\{2}.htm", new string[] { mybookDir, novelID, chapterID.ToString() });
                if (File.Exists(kk))
                {
                    return File.ReadAllText(kk, Encoding.Default);
                }
                else
                {
                    return "无法找到 " + chapterID.ToString() + " 的内容";
                }
            }
        }

        /// <summary>
        /// 获取章节html流
        /// </summary>
        /// <param name="chapterID">章节id</param>
        /// <returns></returns>
        public string getChapterContent(Int64 chapterID)
        {
            string novelID = "";
            if (chapter_book_cache.ContainsKey(chapterID.ToString()))
            {
                novelID = (string)chapter_book_cache[chapterID.ToString()];
            }
            string kk = string.Format("{0}\\chm\\{1}\\{2}.htm", new string[] { mybookDir, novelID, chapterID.ToString() });
            if (File.Exists(kk))
            {
                return File.ReadAllText(kk, Encoding.Default);
            }
            else
            {
                return "无法找到 " + chapterID.ToString() + " 的内容";
            }
        }

        /// <summary>
        /// 获取目录
        /// </summary>
        /// <param name="bookID">书籍ID</param>
        /// <returns>
        /// 0 章节id
        /// 1 分卷
        /// 2 标题
        /// </returns>
        public DataTable getToc(Int64 bookID)
        {
            DataTable toc;
            using (DataView dv = new DataView(chapters, string.Format("novelid = \"{0}\"", bookID.ToString()), "displayorder", DataViewRowState.CurrentRows))
            {
                toc = dv.ToTable();
            }
            return toc;
        }

        public mBook getBook(Int64 bookID)
        {
            DataTable toc = getToc(bookID);

            return null;
        }

        public void get_epub(string bookID)
        {
            DataRow dr;
            using (DataView dv = new DataView(books, "novelid = \"" + bookID.ToString() + "\"", "", DataViewRowState.CurrentRows))
            {
                dr = dv.ToTable().Rows[0];
            }

            string template = "<?xml version=\"1.0\"  encoding=\"UTF-8\"?><package xmlns=\"http://www.idpf.org/2007/opf\" version=\"2.0\" unique-identifier=\"PrimaryID\"><metadata xmlns:dc=\"http://purl.org/dc/elements/1.1/\" xmlns:opf=\"http://www.idpf.org/2007/opf\"><dc:creator opf:role=\"aut\" opf:file-as=\"{0}\">{0}</dc:creator><dc:title>{1}</dc:title><meta name='cover' content='cover'/><dc:identifier opf:scheme=\"ISBN\"/><dc:language>zh-CN</dc:language><dc:publisher>{2}</dc:publisher<dc:description>{3}</dc:description><dc:coverage/><dc:date>{4}</dc:date><dc:rights>{5}</dc:rights><dc:contributor/><dc:type></dc:type><dc:format/><dc:relation/><dc:builder>Sunfish ePub Builder</dc:builder>";
            string opf_head = string.Format(template, new string[] {
            dr[2].ToString(),
            dr[1].ToString(),
            "Sunfish ePub Maker",
            dr[4].ToString(),
            DateTime.Now.ToString("yyyyMMdd HH:mm:ss")+"08:00",
            "没版权"
            });
        }

        public string create_ePub_folder(Int64 bookID)
        {
            DataTable dtinfo = new DataTable();
            OleDbDataAdapter oda = new OleDbDataAdapter(string.Format("select novelid,novelname,author,listurl,brief,bookimg,lb from book_novel where novelid=\"{0}\"  order by displayorder asc", bookID.ToString()), oc); Guid g = new Guid();
            oda.Fill(dtinfo);
            if (dtinfo.Rows.Count == 0)
            {
                Exception ex = new Exception("Could not found novel id= " + bookID.ToString());
                throw (ex);
            }

            DataRow dr = dtinfo.Rows[0];
            string tmpfolder = Path.GetTempPath() + g.ToString() + "\\";
            Directory.CreateDirectory(tmpfolder);
            Directory.CreateDirectory(tmpfolder + "META-INF");

            File.WriteAllText("<?xml version=\"1.0\"?><container version=\"1.0\" xmlns=\"urn:oasis:names:tc:opendocument:xmlns:container\"><rootfiles><rootfile full-path=\"content.opf\" media-type=\"application/oebps-package+xml\"/></rootfiles></container>", tmpfolder + "META-INF\\container.xml", Encoding.UTF8);
            string bookimg = "";
            if (dr[5].ToString() == "")
            {
                bookimg = "nocover.gif";
            }
            else
            {
                bookimg = dr[5].ToString();
            }

            string chapfolder = tmpfolder + dr[0].ToString() + "\\";
            string srcfolder = mybookDir + "\\chm\\" + dr[0].ToString() + "\\";
            Directory.CreateDirectory(chapfolder);
            string template = "<?xml version=\"1.0\"  encoding=\"UTF-8\"?><package xmlns=\"http://www.idpf.org/2007/opf\" version=\"2.0\" unique-identifier=\"PrimaryID\"><metadata xmlns:dc=\"http://purl.org/dc/elements/1.1/\" xmlns:opf=\"http://www.idpf.org/2007/opf\"><dc:creator opf:role=\"aut\" opf:file-as=\"{0}\">{0}</dc:creator><dc:title>{1}</dc:title><dc:identifier opf:scheme=\"GUID\">{6}</dc:identifier><dc:language>zh-CN</dc:language><dc:publisher>{2}</dc:publisher<dc:description>{3}</dc:description><dc:coverage/><dc:date>{4}</dc:date><dc:rights>{5}</dc:rights><dc:contributor/><dc:type></dc:type><dc:format/><dc:relation/><dc:builder>Sunfish ePub Builder</dc:builder></metadata><manifest>";
            string opf_head = string.Format(template, new string[] {
            dr[2].ToString(),
            dr[1].ToString(),
            "Sunfish ePub Maker",
            dr[4].ToString(),
            DateTime.Now.ToString("yyyyMMdd HH:mm:ss")+"+08:00",
            "没版权",
            g.ToString()
            });

            DataTable chapters = new DataTable();
            oda = new OleDbDataAdapter(string.Format("select id,title,novelid,volume from book_novelcontent where novelid=\"{0}\"  order by displayorder asc", bookID.ToString()), oc);
            oda.Fill(chapters);
            string opf_manifest = "<item href=\"style.css\" id=\"style-css\" media-type=\"text/css\"/><item href=\"cover.gif\" id=\"cover1\" media-type=\"image/gif\"/><item href=\"titlepage.xhtml\" id=\"titlepage\" media-type=\"application/xhtml+xml\"/><item href=\"toc.ncx\" media-type=\"application/x-dtbncx+xml\" id=\"ncx\"/></manifest><spine toc=\"ncx\">";
            string opf_spin = "", toc_main = "", strchp = "";
            int ord = 1, offset_start = 0, offset_end = 0;
            foreach (DataRow i in chapters.Rows)
            {
                opf_manifest += string.Format("<item href=\"{1}/{0}.htm\" id=\"{0}\" media-type=\"application/xhtml+xml\"/>", i[0].ToString(), bookID.ToString());
                opf_spin += string.Format("<itemref idref=\"{0}\"/>", i[0].ToString());
                toc_main += string.Format("<navPoint class=\"chapter\" id=\"{1}\" playOrder=\"{3}\"><navLabel><text>{2}</text></navLabel><content src=\"{0}/{1}.htm\"/></navPoint>", new string[] { bookID.ToString(), i[0].ToString(), i[1].ToString(), ord.ToString() });
                strchp = File.ReadAllText(string.Format("{0}{1}.htm", srcfolder, i[0].ToString()), Encoding.Default);
                offset_start = strchp.IndexOf("<!--BookContent Start-->") + "<!--BookContent Start-->".Length;
                offset_end = strchp.IndexOf("<!--BookContent End-->");
                strchp = strchp.Substring(offset_start, (offset_end - offset_start));
                strchp = strchp.Replace("</br></br>", "</p><p>");
                strchp = strchp.Replace("</br>", "</p><p>");
                strchp = strchp.Replace("&nbsp;", "");
                strchp = strchp.Replace("　", "");
                File.WriteAllText(string.Format("{0}{1}.htm", chapfolder, i[0].ToString()), "<html><head><meta http-equiv=\"Content-Type\"  content='text/html; charset=UTF-8'/><link href=\"../style.css\" type=\"text/css\" rel=\"stylesheet\"/></head><body><p>" + strchp + "</p></body></html>", Encoding.UTF8);
                ord++;
            }
            opf_spin += "</spine><guide><reference href=\"titlepage.xhtml\" type=\"cover\" title=\"封面\" /></guide></package>";
            File.WriteAllText(tmpfolder + "content.opf", opf_head + opf_manifest + opf_spin, Encoding.UTF8);
            File.WriteAllText(tmpfolder + "mimetype", "application/epub+zip");
            File.WriteAllText(tmpfolder + "toc.ncx", string.Format("<?xml version='1.0' encoding='utf-8'?><ncx xmlns='http://www.daisy.org/z3986/2005/ncx/' version='2005-1'><head><meta content='{0}' name='dtb:uid'/><meta content='2' name='dtb:depth'/><meta content='0' name='dtb:totalPageCount'/><meta content='0' name='dtb:maxPageNumber'/></head><docTitle><text>{1}</text></docTitle><docAuthor><text>{2}</text></docAuthor><navMap>", new string[] { dr[0].ToString(), dr[1].ToString(), dr[2].ToString() }) + toc_main + "</navMap></ncx>", Encoding.UTF8);
            File.WriteAllText(tmpfolder + "titlepage.xhtml", string.Format("<html><head><meta http-equiv='Content-Type' content='text/html; charset=UTF-8'/><title>Cover</title><style type='text/css' title='override_css'>@page {padding: 0pt; margin:0pt}body { text-align: center; padding:0pt; margin: 0pt;}div { margin: 0pt; padding: 0pt; }</style></head><body><div><img src='{1}/{0}.jpg' alt='cover' style='height: 100%'/></div></body></html>", bookimg, dr[0].ToString()), Encoding.UTF8);

            File.Copy(srcfolder + "style.css", tmpfolder + "style.css");//style.css

            return tmpfolder;
        }
    }

    public class mBook
    {
        public readonly mb MyBook;
        public Int64 BookID;
        public string BookName, BookURL, BookCover, BookAuthor, BookDesc;

        public mBook(ref mb mybook, Int64 bookId)
        {
            MyBook = mybook;
            BookID = bookId;
        }

        public HashSet<mVolume> Volumes;
    }

    public class mVolume
    {
        public readonly mBook Book;
        public int ChapterCount;
        public string VolumeName, DisplayOrder;

        public mVolume(Int64 volumeID)
        {
        }

        public HashSet<mChapter> Chapters;
    }

    public class mChapter
    {
        public Int64 ChapterID, DisplayOrder;
        public string ChapterName, ChapterUrl, ChapterContent;
    }

    public class MyBookInterface
    {
        private string basePath;
        private DataTable books;
        private string cachedBookID;
        private Hashtable cachedList;
        private OleDbConnection dbo;
        private string dbPath;
        private bool isCached = false;

        public string create_ePub_folder(string bookID)
        {
            DataTable dtinfo = new DataTable();
            OleDbDataAdapter oda = new OleDbDataAdapter(string.Format("select novelid,novelname,author,listurl,brief,bookimg,lb from book_novel where novelid=\"{0}\"  order by displayorder asc", bookID.ToString()), dbo);
            Guid g = Guid.NewGuid();

            oda.Fill(dtinfo);
            if (dtinfo.Rows.Count == 0)
            {
                Exception ex = new Exception("Could not found novel id= " + bookID.ToString());
                throw (ex);
            }

            DataRow dr = dtinfo.Rows[0];
            string tmpfolder = Path.GetTempPath() + g.ToString() + "\\";
            Directory.CreateDirectory(tmpfolder);
            Directory.CreateDirectory(tmpfolder + "META-INF");
            string chapfolder = tmpfolder + dr[0].ToString() + "\\";
            string srcfolder = basePath + "\\chm\\" + dr[0].ToString() + "\\";
            Directory.CreateDirectory(chapfolder);
            File.WriteAllText(tmpfolder + "META-INF\\container.xml", "<?xml version=\"1.0\"?><container version=\"1.0\" xmlns=\"urn:oasis:names:tc:opendocument:xmlns:container\"><rootfiles><rootfile full-path=\"content.opf\" media-type=\"application/oebps-package+xml\"/></rootfiles></container>", Encoding.UTF8);
            string bookimg = srcfolder + dr[5].ToString();
            if (File.Exists(dr[5].ToString()))
            {
                //bookimg = Path.GetFileName(dr[5].ToString());

                System.Drawing.Image cimg = System.Drawing.Image.FromFile(dr[5].ToString());
                bookimg = tmpfolder + "cover.jpg";
                cimg.Save(bookimg, System.Drawing.Imaging.ImageFormat.Jpeg);

                //File.Copy(dr[5].ToString(), tmpfolder + bookimg);
            }
            else
            {
                if (File.Exists(bookimg))
                {
                    System.Drawing.Image cimg = System.Drawing.Image.FromFile(bookimg);
                    bookimg = tmpfolder + "cover.jpg";
                    cimg.Save(bookimg, System.Drawing.Imaging.ImageFormat.Jpeg);
                    //File.Copy(bookimg, tmpfolder + dr[5].ToString());
                    // bookimg = dr[5].ToString();
                }
                else
                {
                    //bookimg = dr[5].ToString();
                    //bookimg = "nocover.gif";
                    bookimg = basePath + "\\chm\\nocover.gif";

                    // File.Copy(basePath + "\\chm\\nocover.gif", tmpfolder + "nocover.gif");
                    System.Drawing.Image cimg = System.Drawing.Image.FromFile(bookimg);
                    bookimg = tmpfolder + "cover.jpg";
                    cimg.Save(bookimg, System.Drawing.Imaging.ImageFormat.Jpeg);
                    //  bookimg = tmpfolder + "cover.jpg";
                }
            }

            File.WriteAllText(tmpfolder + "titlepage.xhtml", "<?xml version='1.0' encoding='utf-8'?><html xmlns='http://www.w3.org/1999/xhtml' xml:lang='zh-CN'><head><meta http-equiv='Content-Type' content='text/html; charset=UTF-8'/><title>Cover</title></head><body><img src='cover.jpg' alt='cover' class='cover' style='height: 100%'/></body></html>", Encoding.UTF8);

            string template = "<?xml version=\"1.0\"  encoding=\"UTF-8\"?>\n<package xmlns=\"http://www.idpf.org/2007/opf\" version=\"2.0\" unique-identifier=\"PrimaryID\">\n<metadata xmlns:dc=\"http://purl.org/dc/elements/1.1/\" xmlns:opf=\"http://www.idpf.org/2007/opf\">\n<dc:title>{1}</dc:title>\n<dc:creator>{0}</dc:creator>\n<meta name='cover' content='cover-image'/>\n<dc:identifier opf:scheme=\"GUID\">{6}</dc:identifier>\n<dc:language>zh-CN</dc:language>\n<dc:publisher>{2}</dc:publisher>\n<dc:description>{3}</dc:description><dc:subject>网络小说</dc:subject><dc:coverage/><dc:date>{4}</dc:date>\n<dc:rights>{5}</dc:rights><dc:contributor/>\n<dc:type></dc:type><dc:format/><dc:relation/><dc:builder>Sunfish ePub Builder</dc:builder> </metadata><manifest>";
            string opf_head = string.Format(template, new string[] {
            dr[2].ToString(),
            dr[1].ToString(),
            "Sunfish ePub Maker",
            dr[4].ToString(),
            DateTime.Now.ToString("yyyy-MM-dd"),
            "没版权",
            g.ToString()
            });

            DataTable chapters = new DataTable();
            oda = new OleDbDataAdapter(string.Format("select id,title,novelid,volume from book_novelcontent where novelid=\"{0}\"  order by displayorder asc", bookID.ToString()), dbo);
            oda.Fill(chapters);
            string opf_manifest = "<item href=\"style.css\" id=\"style-css\" media-type=\"text/css\"/><item href=\"cover.jpg\" id=\"cover-image\" media-type=\"image/jpeg\"/><item href=\"titlepage.xhtml\" id=\"titlepage\" media-type=\"application/xhtml+xml\"/><item href=\"toc.ncx\" media-type=\"application/x-dtbncx+xml\" id=\"ncx\"/>";
            string opf_spin = "", toc_main = "", strchp = "";
            int ord = 1, offset_start = 0, offset_end = 0;
            foreach (DataRow i in chapters.Rows)
            {
                opf_manifest += string.Format("<item href=\"{1}/{0}.htm\" id=\"page{0}\" media-type=\"application/xhtml+xml\"/>\n", i[0].ToString(), bookID.ToString());
                opf_spin += string.Format("<itemref idref=\"page{0}\"/>\n", i[0].ToString());
                toc_main += string.Format("<navPoint class=\"chapter\" id=\"{1}\" playOrder=\"{3}\"><navLabel><text>{2}</text></navLabel><content src=\"{0}/{1}.htm\"/></navPoint>\n", new string[] { bookID.ToString(), i[0].ToString(), i[1].ToString(), ord.ToString() });
                if (File.Exists(string.Format("{0}{1}.htm", srcfolder, i[0].ToString())))
                {
                    strchp = File.ReadAllText(string.Format("{0}{1}.htm", srcfolder, i[0].ToString()), Encoding.Default);
                    offset_start = strchp.IndexOf("<!--BookContent Start-->") + "<!--BookContent Start-->".Length;
                    offset_end = strchp.IndexOf("<!--BookContent End-->");
                    strchp = strchp.Substring(offset_start, (offset_end - offset_start));
                    strchp = strchp.Replace("<br>", "</p>\n<p>");
                    strchp = strchp.Replace("</br>", "</p>\n<p>");
                    strchp = strchp.Replace("&nbsp;", "");
                    strchp = strchp.Replace("</p>\n<p></p>\n<p>\n", "</p>\n<p>");
                    //strchp.Replace("<br>&nbsp;&nbsp;", "<p>");
                    strchp = strchp.Replace("　", "");
                    strchp = strchp.Replace("&nbsp;", "");
                    File.WriteAllText(string.Format("{0}{1}.htm", chapfolder, i[0].ToString()), "<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"zh-CN\"><head><meta http-equiv='Content-Type' content='text/html; charset=UTF-8'/><link href=\"../style.css\" type=\"text/css\" rel=\"stylesheet\"/><title>" + i[1].ToString() + "</title></head><body>\n<p>" + strchp + "</p>\n</body></html>", Encoding.UTF8);
                }
                else
                {
                    strchp = "书库中对应文件不存在,请更新后重新下载";
                    File.WriteAllText(string.Format("{0}{1}.htm", chapfolder, i[0].ToString()), "<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"zh-CN\"><head><meta http-equiv='Content-Type' content='text/html; charset=UTF-8'/><link href=\"../style.css\" type=\"text/css\" rel=\"stylesheet\"/><title>" + i[1].ToString() + "</title></head><body>\n<p>" + strchp + "</p>\n</body></html>", Encoding.UTF8);
                }
                ;
                ord++;
            }
            opf_spin += "</spine><guide><reference href=\"titlepage.xhtml\" type=\"cover\" title=\"Cover\" /></guide></package>";
            File.WriteAllText(tmpfolder + "content.opf", opf_head + opf_manifest + "</manifest><spine toc=\"ncx\"><itemref idref='titlepage' type='cover' title='Cover'/>" + opf_spin, Encoding.UTF8);
            File.WriteAllText(tmpfolder + "mimetype", "application/epub+zip");
            File.WriteAllText(tmpfolder + "toc.ncx", string.Format("<?xml version='1.0' encoding='utf-8'?><ncx xmlns='http://www.daisy.org/z3986/2005/ncx/' version='2005-1'><head><meta content='{0}' name='dtb:uid'/><meta content='2' name='dtb:depth'/><meta content='0' name='dtb:totalPageCount'/><meta content='0' name='dtb:maxPageNumber'/></head><docTitle><text>{1}</text></docTitle><docAuthor><text>{2}</text></docAuthor><navMap><navPoint class=\"titlepage\" id=\"titlepage\" playOrder=\"0\"><navLabel><text>Cover</text></navLabel><content src=\"titlepage.xhtml\"/></navPoint>\n", new string[] { dr[0].ToString(), dr[1].ToString(), dr[2].ToString() }) + toc_main + "</navMap></ncx>", Encoding.UTF8);

            File.Copy(basePath + "\\chm\\style.css", tmpfolder + "style.css");//style.css

            return tmpfolder;
        }

        public MyBookInterface(string DBPath)
        {
            if (File.Exists(DBPath))
            {
                this.dbPath = DBPath;
                this.dbo = new OleDbConnection(this.MyBook66ConnectionString);
                try
                {
                    this.basePath = Path.GetDirectoryName(this.dbPath);
                    this.dbo.Open();
                    this.populateBooks();
                }
                catch (Exception exception)
                {
                    throw exception;
                }
            }
            else
            {
                FileNotFoundException exception2 = new FileNotFoundException(string.Format("文件{0}无法找到", DBPath));
                throw exception2;
            }
        }

        private void addToZipSteam(ref ZipOutputStream into, string entryName, ref MemoryStream resource)
        {
            ZipEntry entry = new ZipEntry(entryName);
            resource.Position = 0L;
            into.PutNextEntry(entry);
            byte[] buffer = new byte[resource.Length];
            resource.Read(buffer, 0, buffer.Length);
            into.Write(buffer, 0, buffer.Length);
            into.CloseEntry();
        }

        private MemoryStream get_ePub_Content_OPF(string bookID)
        {
            MemoryStream stream = new MemoryStream();
            StreamWriter writer = new StreamWriter(stream);
            DataRow[] rowArray = this.books.Select(string.Format("NovelID = {0}", bookID));
            if (rowArray.GetLength(0) == 0)
            {
                throw new Exception(string.Format("无法找到NovelID {0} ", bookID));
            }
            string str = rowArray[0]["NovelName"].ToString();
            string str2 = rowArray[0]["Author"].ToString();
            string str3 = rowArray[0]["ListUrl"].ToString();
            string str4 = rowArray[0]["Brief"].ToString();
            writer.WriteLine("<?xml version=\"1.0\" encoding=\"utf-8\"?>");
            writer.WriteLine("<!DOCTYPE package PUBLIC \"+//ISBN 978-7-308-05831-5//DTD OEB 1.2 Package//EN\" \"http://openebook.org/dtds/oeb-1.2/oebpkg12.dtd\"> <package unique-identifier=\"bookid\" xmlns:opf=\"http://www.idpf.org/ 2007/opf\" xmlns=\"http://www.idpf.org/2007/opf\" version=\"2.0\">");
            writer.WriteLine("<metadata>");
            writer.WriteLine("<dc-metadata xmlns:dc=\"http://purl.org/dc/elements/1.1/\"xmlns:dcterms=\"http://purl.org/dc/terms/\" xmlns:xsi=\"http:// www.w3.org/2001/XMLSchema-instance\">");
            writer.WriteLine(string.Format("<dc:title>{0}</dc:title>", str));
            writer.WriteLine("<dc:publisher>Sunfish MyBook66 Exporter.ePub</dc:publisher>");
            writer.WriteLine(string.Format("<dc:creator>{0}</dc:creator>", str2));
            writer.WriteLine(string.Format("<dc:contributor>{0}</dc:contributor>", "Sunfish"));
            writer.WriteLine("<dc:subject>Online Novel</dc:subject>");
            writer.WriteLine(string.Format("<dc:description>{0}<dc:description>", str4));
            writer.WriteLine(string.Format("<dc:date>{0}</dc:date>", DateTime.Now.ToString("yyyy-MM-dd")));
            writer.WriteLine("<dc:type>Novel</dc:type>");
            writer.WriteLine("<dc:format>Text/html(.html,.htm)</dc:format>");
            writer.WriteLine(string.Format("<dc:identifier id=\"bookid\" opf:scheme=\"GUID\">guid:{0}</dc:identifier>", Guid.NewGuid().ToString()));
            writer.WriteLine(string.Format("<dc:source>{0}</dc:source>", str3));
            writer.WriteLine("<dc:language>chi</dc:language>");
            writer.WriteLine("<dc:relation></dc:relation>");
            writer.WriteLine("<dc:coverage></dc:coverage>");
            writer.WriteLine("<dc:rights>来源无法验证合法性，无DRM</dc:rights>");
            writer.WriteLine("</dc-metadata></metadata>");
            DataTable table = this.getData(string.Format("\r\nselect id,title,downdate,downtime,comefrom,Volume,wordnums\r\nFROM book_NovelContent\r\nwhere novelid = '{0}'\r\norder by displayorder asc\r\n            ", bookID));
            writer.WriteLine("<manifest>");
            writer.WriteLine("<item id=\"ncx\" href=\"toc.ncx\" media-type=\"application/x-dtbncx +xml\"/>");
            writer.WriteLine("<item id=\"style\" href=\"style.css\" media-type=\"text/css\"/>");
            writer.WriteLine("<item id=\"cover\" href=\"cover.htm\" media-type=\"text/html\"/>");
            foreach (DataRow row in table.Rows)
            {
                writer.WriteLine(string.Format("<item id=\"{0}\" href=\"content\\{0}.html\" media-type=\"text/html\"/>", row["id"].ToString().Trim()));
            }
            writer.WriteLine("<spine toc=\"ncx\">");
            writer.WriteLine("<itemref idref=\"cover\"/>");
            foreach (DataRow row in table.Rows)
            {
                writer.WriteLine(string.Format("<itemref idref=\"{0}\" />", row["id"].ToString().Trim()));
            }
            writer.WriteLine("</spine>");
            writer.WriteLine("</manifest>");
            writer.Flush();
            return stream;
        }

        private static MemoryStream get_ePub_META_INF()
        {
            MemoryStream stream = new MemoryStream();
            StreamWriter writer = new StreamWriter(stream);
            writer.WriteLine("<?xml version='1.0' encoding='utf-8'?>");
            writer.WriteLine("<container xmlns=\"urn:oasis:names:tc:opendocument:xmlns:container\" version=\"1.0\">");
            writer.WriteLine("<rootfiles>");
            writer.WriteLine("<rootfile full-path=\"OEBPS/content.opf\" media-type=\"application/oebps-package+xml\" />");
            writer.WriteLine("</rootfiles>");
            writer.WriteLine("</container>");
            writer.Flush();
            return stream;
        }

        private static MemoryStream get_ePub_mimetype()
        {
            MemoryStream stream = new MemoryStream();
            StreamWriter writer = new StreamWriter(stream);
            writer.WriteLine("application/epub+zip");
            writer.Flush();
            return stream;
        }

        private MemoryStream get_ePub_TOC_NCX(string bookID)
        {
            MemoryStream stream = new MemoryStream();
            StreamWriter writer = new StreamWriter(stream);
            writer.WriteLine("<?xml version=\"1.0\" encoding=\"utf-8\"?>");
            writer.WriteLine("<!DOCTYPE ncx PUBLIC \"-//NISO//DTD ncx 2005-1//EN\" \"http:// www.daisy.org/z3986/2005/ncx-2005-1.dtd\">");
            writer.WriteLine("<ncx version=\"2005-1\" xmlns=\"http://www.daisy.org/z3986/2005/ ncx/\">");
            writer.WriteLine("<head><meta name=\"dtb:uid\" content=\" \"/><meta name=\"dtb:depth\" content=\"-1\"/>");
            writer.WriteLine("<meta name=\"dtb:totalPageCount\" content=\"0\"/><meta name=\"dtb:maxPageNumber\" content=\"0\"/></head>");
            writer.WriteLine(string.Format("<docTitle>{0}</docTitle>", this.getBookNameFromID(bookID)));
            writer.WriteLine(string.Format("<docAuthor>{0}</docAuthor>", "Sunfish Exporter"));
            writer.WriteLine("<naviMap>");
            int id = 1;
            string str = "正文";
            DataTable table = this.getData(string.Format("\r\nselect id,title,downdate,downtime,comefrom,Volume,wordnums\r\nFROM book_NovelContent\r\nwhere novelid = '{0}'\r\norder by displayorder asc\r\n            ", bookID));
            writer.WriteLine("<naviPoint id=\"snav_1\" playOrder=\"1\"><navLabel>正文</navLabel> ");
            foreach (DataRow row in table.Rows)
            {
                id++;
                if ((row["Volume"].ToString().Trim() == "") || (row["Volume"].ToString().Trim() == str))
                {
                    writer.WriteLine(this.getNaviPoint(id, row["title"].ToString().Trim(), string.Format(@"content\{0}.html", row["id"].ToString())));
                }
                else
                {
                    str = row["Volume"].ToString().Trim();
                    writer.WriteLine(string.Format("</navPoint><naviPoint id=\"snav_{0}\" playOrder=\"{0}\"><navLabel>{1}</navLabel>", id.ToString(), str));
                    id++;
                    writer.WriteLine(this.getNaviPoint(id, row["title"].ToString().Trim(), string.Format(@"content\{0}.html", row["id"].ToString())));
                }
            }
            writer.WriteLine("</navPoint></naviMap>");
            writer.Flush();
            return stream;
        }

        public MemoryStream getBook_ePub(string bookID)
        {
            MemoryStream baseOutputStream = new MemoryStream();
            ZipOutputStream into = new ZipOutputStream(baseOutputStream);
            into.SetLevel(9);
            if (this.getBookNameFromID(bookID) == "")
            {
                return null;
            }
            into.SetComment(string.Format("ePub create by Sunfish Exporter\nData Collected from MyBook66\nFile Created on {0}", DateTime.Now.ToString("yyyy-MM-dd")));
            MemoryStream resource = get_ePub_mimetype();
            this.addToZipSteam(ref into, "minetype", ref resource);
            resource = get_ePub_META_INF();
            this.addToZipSteam(ref into, @"META-INF\container.xml", ref resource);
            into.Flush();
            baseOutputStream.Flush();
            into.IsStreamOwner = false;
            into.Close();
            baseOutputStream.Position = 0L;
            return baseOutputStream;
        }

        public MemoryStream getBookFB2(string bookID)
        {
            DataRow[] rowArray = this.books.Select(string.Format("NovelID = {0}", bookID));
            if (rowArray.GetLength(0) == 0)
            {
                throw new Exception(string.Format("无法找到NovelID {0} ", bookID));
            }
            string str = rowArray[0]["NovelName"].ToString();
            string str2 = rowArray[0]["Author"].ToString();
            string str3 = rowArray[0]["ListUrl"].ToString();
            DataTable table = this.getData(string.Format("\r\nselect id,title,downdate,downtime,comefrom,Volume,wordnums\r\nFROM book_NovelContent\r\nwhere novelid = '{0}'\r\norder by displayorder asc\r\n            ", bookID));
            string strA = "";
            ArrayList list = new ArrayList();
            foreach (DataRow row in table.Rows)
            {
                if (string.Compare(strA, "", false) == 0)
                {
                    strA = (string.Compare(row["Volume"].ToString(), "", false) != 0) ? row["Volume"].ToString() : "正文";
                    list.Add(toUTF8(string.Format("<section><title><p>{0}</p></title>", strA)));
                }
                else if ((string.Compare(row["Volume"].ToString(), strA, false) != 0) && (row["Volume"].ToString().Trim() != ""))
                {
                    strA = row["Volume"].ToString();
                    list.Add(toUTF8(string.Format("</section><section><title><p>{0}</p></title>", strA)));
                }
                string str5 = this.getChapterContent(row["id"].ToString(), bookID);
                if (str5.Contains("<!--BookContent Start-->"))
                {
                    str5 = str5.Substring(str5.IndexOf("<!--BookContent Start-->") + 0x18, str5.IndexOf("<!--BookContent End-->") - (str5.IndexOf("<!--BookContent Start-->") + 0x18)).Replace("&nbsp;", " ").Replace("<br>", "</p><p>").Replace("</br>", "</p><p>").Replace("<br/>", "</p><p>").Replace("</ br>", "</p><p>").Replace("<br />", "</p><p>");
                }
                list.Add(toUTF8(string.Format("<section><title><p>{0}</p></title><p>字数:{2}</p><p>{1}</p></section>", row["Title"].ToString(), str5, row["WordNums"].ToString())));
            }
            list.Add(toUTF8("</section><section>"));
            MemoryStream stream = new MemoryStream();
            StreamWriter writer = new StreamWriter(stream, Encoding.UTF8);
            writer.WriteLine("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
            writer.WriteLine("<FictionBook xmlns:xlink=\"http://www.w3.org/1999/xlink\" xmlns=\"http://www.gribuser.ru/xml/fictionbook/2.0\">");
            writer.WriteLine("<description><title-info><genre match = \"0\">ChineseNetNovels</genre>");
            writer.WriteLine("<author><first-name>MyBook66 Downloaded</first-name><last-name>Almost All Piracy....</last-name></author>");
            writer.WriteLine(string.Format("<book-title>{0}</book-title>", str));
            writer.WriteLine(string.Format("<date value =\"{0}\">{1}</date>", DateTime.Today, DateTime.Today.Year));
            writer.WriteLine("<lang>ZH_CN</lang></title-info>");
            writer.WriteLine(string.Format("<document-info><author><nickname>{0}</nickname></author>", str2));
            writer.WriteLine("<program-used>MyBook66_To_FB2</program-used></document-info></description>");
            writer.WriteLine(string.Format("<body><title><p>{0}</p></title>", str));
            writer.WriteLine(string.Format("\r\n<p>书籍作者:{0}</p>\r\n<p>书籍制作于:{1}</p>\r\n<p>书籍制作者:{2}</p>\r\n<p>书籍制作工具:{3}</p>\r\n<p>书籍数据来源于:{4}</p>\r\n<p>原始数据来源于:{5}</p>\r\n", (object[])new string[] { str2, DateTime.Now.ToString("yyyy-MM-dd hh:mm:ss"), "Sunfish", "MyBook66 FB2 Exporter", "华之城 小说下载阅读器", str3 }));
            for (int i = 0; i < list.Count; i++)
            {
                writer.WriteLine((string)list[i]);
            }
            writer.WriteLine("</body></FictionBook>");
            writer.Flush();
            return stream;
        }

        public MemoryStream getBookFBZ(string bookID)
        {
            MemoryStream baseOutputStream = new MemoryStream();
            MemoryStream stream2 = this.getBookFB2(bookID);
            ZipOutputStream stream3 = new ZipOutputStream(baseOutputStream)
            {
                IsStreamOwner = false
            };
            stream3.SetLevel(9);
            byte[] buffer = stream2.GetBuffer();
            ZipEntry entry2 = new ZipEntry(string.Format("{0}.fb2", this.getBookNameFromID(bookID)))
            {
                DateTime = DateTime.Now,
                Size = buffer.Length
            };
            ZipEntry entry = entry2;
            stream3.PutNextEntry(entry);
            stream3.Write(buffer, 0, buffer.Length);
            stream3.Finish();
            stream3.Close();
            return baseOutputStream;
        }

        public string getBookNameFromID(string bookID)
        {
            if (this.books != null)
            {
                DataRow[] rowArray = this.books.Select(string.Format("NovelID={0}", bookID));
                if (rowArray.Length != 0)
                {
                    return rowArray[0]["NovelName"].ToString();
                }
                return "";
            }
            return "";
        }

        public string getBookPath(string bookID)
        {
            return string.Format(@"{1}\chm\{0}\", bookID, this.basePath);
        }

        public string getChapterContent(string chapterID, string bookID)
        {
            string path = string.Format(@"{0}\chm\{1}\{2}.htm", (object[])new string[] { this.basePath, bookID, chapterID });
            if (File.Exists(path))
            {
                return File.ReadAllText(path, Encoding.Default);
            }
            return "";
        }

        public DataTable GetChapterList(string bookID)
        {
            return this.getData(string.Format("select id,title,bIsRead from book_novelContent where NovelID='{0}' order by displayorder asc", bookID));
        }

        public string getChapterPath(string chapterID, string bookID)
        {
            if (string.Compare(bookID, this.CachedBookID, false) != 0)
            {
                this.CachedBookID = bookID;
            }
            if (this.cachedList.ContainsKey(chapterID))
            {
                string path = string.Format(@"{0}\chm\{1}\{2}.htm", (object[])new string[] { this.basePath, bookID, chapterID });
                return (File.Exists(path) ? path : "");
            }
            return "";
        }

        public string getChapterTitle(string chapterID, string bookID)
        {
            if (string.Compare(bookID, this.CachedBookID, false) != 0)
            {
                this.CachedBookID = bookID;
            }
            return (this.cachedList.ContainsKey(chapterID) ? ((string)this.cachedList[chapterID]) : "");
        }

        private DataTable getData(string sSQL)
        {
            DataTable dataTable = new DataTable();
            using (OleDbDataAdapter adapter = new OleDbDataAdapter(sSQL, this.dbo))
            {
                adapter.Fill(dataTable);
            }
            return dataTable;
        }

        private string getNaviPoint(int id, string title, string filename)
        {
            return string.Format("<navPoint id=\"snav_{0}\" playOrder=\"{0}\"><navLabel>{1}</navLabel><content src=\"{2}\"/></navPoint>", (object[])new string[] { id.ToString(), title, filename });
        }

        private void populateBooks()
        {
            this.books = this.getData("\r\nselect tba.NovelID,tba.NovelName,tba.LB as GroupID,tbb.mc as GroupName,\r\n        tba.Author,tba.ListUrl,tba.Brief\r\nfrom book_novel tba, dic_noveltype tbb\r\nwhere tba.LB=tbb.DM\r\norder by tba.lb");
        }

        public void setRead(string bookID)
        {
            OleDbCommand command = this.dbo.CreateCommand();
            command.CommandText = string.Format("update book_novelContent set bIsRead='1' where novelid='{0}'", bookID);
            command.ExecuteNonQuery();
            command.Dispose();
        }

        public static string toUTF8(string inStr)
        {
            return inStr;
        }

        public string CachedBookID
        {
            get
            {
                return this.cachedBookID;
            }
            set
            {
                this.cachedBookID = value;
                try
                {
                    using (DataTable table = this.getData(string.Format("SELECT id,title\r\nFROM book_NovelContent\r\nwhere novelid = '{0}'\r\norder by displayorder asc", value)))
                    {
                        this.isCached = true;
                        this.cachedList = new Hashtable();
                        foreach (DataRow row in table.Rows)
                        {
                            this.cachedList.Add(row["id"].ToString(), row["title"].ToString());
                        }
                    }
                }
                catch (Exception exception)
                {
                    Exception exception2 = new Exception(string.Format("缓冲书籍{0}的目录失败,详情:{1}", value, exception.Message));
                    this.isCached = false;
                    throw exception2;
                }
            }
        }

        public bool IsCached
        {
            get
            {
                return this.isCached;
            }
        }

        private string MyBook66ConnectionString
        {
            get
            {
                return string.Format("Provider=Microsoft.Jet.OLEDB.4.0;Data Source={0}", this.dbPath);
            }
        }

        public string MyBook66DBPath
        {
            get
            {
                return this.dbPath;
            }
        }

        public DataTable MyBook66Structure
        {
            get
            {
                return this.books;
            }
        }

        public DataTable UnReadBooks
        {
            get
            {
                return this.getData("select tba.NovelID,tba.NovelName,tba.LB as GroupID,tbb.mc as GroupName,\r\n        tba.Author,tba.ListUrl,tbc.cnt as UnRead\r\nfrom book_novel tba, dic_noveltype tbb,(select count(id) as cnt,novelid from book_novelContent where bisread='0' group by novelid )tbc\r\nwhere tba.LB=tbb.DM\r\n  and tba.novelid=tbc.novelid\r\norder by tba.lb");
            }
        }
    }
}